/**
 *  Model1
 *  Author: hakute
 *  Description: 
 */
model Model9
global {
/** Insert the global definitions, variables and actions here */
	file shape_file_bounds <- file ( '../includes/Batiment/Bounds.shp' ) ;
	file shape_file_obtacles0 <- file ( '../includes/Batiment/Obtacles.shp' ) ;
	file shape_file_obtacles1 <- file ( '../includes/Batiment/Obtacles1.shp' ) ;
	file shape_file_obtacles2 <- file ( '../includes/Batiment/Obtacles2.shp' ) ;
	file shape_file_obtacles;
	file shape_file_areas <- file ( '../includes/Batiment/Area.shp' ) ;
	file shape_file_safe_areas0 <- file ( '../includes/Batiment/Save_place.shp' ) ;
	file shape_file_safe_areas1 <- file ( '../includes/Batiment/Save_place1.shp' ) ;
	file shape_file_safe_areas2 <- file ( '../includes/Batiment/Save_place2.shp' ) ;
	file shape_file_safe_areas ;
	file shape_file_sonneur <- file ( '../includes/Batiment/Sonneur.shp' ) ;
	file shape_file_path <- file ( '../includes/Batiment/Path.shp' ) ;
	list list_areas of : areas ;
	list list_obtacles of : obtacles ;
	list list_safe_areas of : safe_areas ;
	graph graph_path ;
	bool sonneur ;
	int sonneur_fois <- 0 ;
	string path_fire <- '../images/fire.png' ;
	string path_smoke <- '../images/smoke.png' ;
	bool sortie1 <-true category: "Sorties";
	bool sortie2 <-true category: "Sorties";
	
	//Statique
	int n_evacuees_safe <-0;
	int sum_duree_quitte <-0;
	int sum_puissance <-0;
	int n_evacuees_mort <-0;
	
	//evacuees
	int n_evacuees <-20 max:1000 min:10 category : 'Evacuees';
	float taile_max <- 20.0 max: 50.0 min:20.0 category : 'Evacuees' ;
	int puissance_max <- 150 max: 200 min: 100 category : 'Evacuees';
	float vitesse_normal <-5.0 max: 50.0 min: 1.0 category : 'Evacuees';
	float vitesse_max <- 10.0 max: 100.0 min:1.0 category : 'Evacuees';
	
	//Feux
	int n_feux <-10 max:100 min: 1 category: 'Feux';
	float feux_taile_max <- 10.0 max: 50.0 min:1.0 category: 'Feux';
	float feux_rayon_effectuer <- 100.0 max: 100.0 min: 0.0 category: 'Feux'  ;
	float feux_vitesse_propagation <- 10.0 max: 10.0 min: 0.0 category: 'Feux';
	int feux_vitesse_creer <- 2 max:10 min:0 category: 'Feux' ;
	float probabilite_burning <-0.01 min:0.001 max: 1.0 category:'Feux';
	
	//fumme
	float vitesse_deplacer_max <-40.0 max:100.0 min: 10.0 category: 'Fumme';
	
	//Sonneur
	float sonneur_rayon_detection <- 100.0 max:1000.0 min:10.0 category: 'Sonneur de incendie';
	int sonneur_duree <- 200 max:1000 min:100 category: 'Sonneur de incendie';
	
	init {
		if ((sortie1=true)and(sortie2=false)){
			set shape_file_safe_areas <- shape_file_safe_areas1;
			set shape_file_obtacles <- shape_file_obtacles1;
		}
		if ((sortie1=false)and(sortie2=true)){
			set shape_file_safe_areas <- shape_file_safe_areas2;
			set shape_file_obtacles <- shape_file_obtacles2;
		}
		if ((sortie1=true)and(sortie2=true)){
			set shape_file_safe_areas <- shape_file_safe_areas0;
			set shape_file_obtacles <- shape_file_obtacles0;
		}
		create areas from : shape_file_areas ;
		create obtacles from : shape_file_obtacles ;
		create safe_areas from : shape_file_safe_areas ;
		create sonneur_normal from : shape_file_sonneur ;
		create path_emergent from : shape_file_path ;
		set list_areas <- areas as list ;
		set list_obtacles <- obtacles as list ;
		set list_safe_areas <- safe_areas as list ;
		set graph_path <- as_edge_graph ( list ( path_emergent ) )with_optimizer_type "Dijkstra" ;
		set sonneur <- false ;
		create evacuees_normal number : n_evacuees {
			set location <- any_point_in ( one_of ( areas ) ) ;
		}
		create feux_potentiel number : n_feux {
			set location <- any_point_in ( one_of ( list_obtacles ) ) ;
		}
	}
}
environment bounds : shape_file_bounds torus : false ;
entities {
/** Insert here the definition of the species of agents */

//Initial
	species obtacles {
		string type ;
		rgb color <- rgb ( [ 155 , 0 , 0 ] ) ;
		aspect base {
			draw geometry : shape color : color ;
		}
	}
	species areas {
		rgb color <- rgb ( 'white' ) ;
		aspect base {
			draw geometry : shape color : color ;
		}
	}
	species safe_areas {
		rgb color <- rgb ( 'white' ) ;
		aspect base {
			draw geometry : shape color : color ;
		}
	}
	species path_emergent {
		rgb color <- rgb ( 'black' ) ;
		aspect base {
			draw geometry : shape color : color ;
		}
	}

	//evacuees
	species evacuees_normal skills : [ moving , situated ] control : fsm {
		float taile <- rnd ( taile_max ) + 20.0 ;
		rgb color <- rgb ( [ rnd ( 255 ) , rnd ( 255 ) , rnd ( 255 ) ] ) ;
		int puissance <- puissance_max ;
		int niveauEffectue <- rnd ( 3 ) + 1 ;
		float vitesseMax <- vitesse_max ;
		float vitesseActuelle <- vitesse_normal ;
		int direction <- 180 ;
		float range_voir <- 100.0 ;
		float range_min <-20.0;
		agent danger <- nil ;
		reflex move_normal when : ( danger = nil ) {
			do action: move_normal ;
			let voir_feux <- ( self neighbours_at ( range_voir ) of_species feux ) ;
			ask voir_feux {
				set myself . danger <- self ;
			}
			let voir_fumee <- ( self neighbours_at ( range_voir ) of_species fumee) ;
			ask voir_fumee {
				set myself . danger <- self ;
			}
		}
		reflex emergent when : ( ( danger != nil ) or ( sonneur = true ) ) {
			do action: emergent ;
		}
		action move_normal {
				let others type: evacuees_normal <- one_of ( ( (self neighbours_at range_min) of_species evacuees_normal) sort_by (self distance_to each) );
				if (others!=nil){
					set direction <- (self towards others) - 180;
					do move speed: vitesseActuelle heading: direction;
				}
				else {
					do wander speed : vitesseActuelle amplitude : direction bounds : list_areas;
				}
		}
		action emergent {
			create evacuees_urgent {
				set self . color <- myself . color ;
				set self . taile <- myself . taile ;
				set self . location <- myself . location ;
				set self . puissance <- myself. puissance;
			}
			do action: die ;
		}
		aspect base {
			draw shape : circle size : taile color : color ;
			//draw shape: circle color: rgb('orange') size: range_voir*2+taile empty: true;
			//draw shape: circle color: rgb('green') size: range_entendre*2+taile empty: true;
		}
	}
	species evacuees_urgent skills : [ moving , situated ] control : fsm {
		float taile <- rnd ( taile_max ) + 20.0 ;
		rgb color <- rgb ( [ rnd ( 255 ) , rnd ( 255 ) , rnd ( 255 ) ] ) ;
		int puissance <- puissance_max ;
		int niveauEffectue <- rnd ( 3 ) + 1 ;
		float vitesseMax <- vitesse_max ;
		float vitesseActuelle <- vitesse_normal ;
		int heading <- 180 ;
		float range_voir <- 100.0 ;
		float range_min <-20.0;
		int duree <-0;
		safe_areas direction ;
		
		action decrement_puissance {
			if ( ( niveauEffectue < 2 ) and ( taile < 20.0 ) ) {
				set puissance <- puissance - 20 ;
			}
			if ( ( niveauEffectue = 3 ) and ( taile < 20.0 ) ) {
				set puissance <- puissance - 10 ;
			}
			if ( ( niveauEffectue = 3 ) and ( taile >= 20.0 ) ) {
				set puissance <- puissance - 5 ;
			}
			if ( puissance <= 0 ) {
				do action: dead ;
			}
		}
		action dead {
			create evacuees_mort {
				set self . color <- [ 0 , 0 , 0 ] as rgb ;
				set self . taile <- myself . taile ;
				set self . location <- myself . location ;
				set n_evacuees_mort <- n_evacuees_mort + 1;
			}
			do action: die ;
		}
		reflex moving2Safe {
			set duree <- duree +1;
			let min <- list_safe_areas min_of (self distance_to each);
			ask list_safe_areas{
				if((myself distance_to self)<=min){
					set myself.direction <- self ;
				}
			}
			//set but <- any_point_in (areas_safe);
			let others type: evacuees_urgent <- one_of ( ( (self neighbours_at range_min) of_species evacuees_urgent) sort_by (self distance_to each) );
				if (others!=nil){
					//if (self.taile <= others.taile){
					set heading <- (self towards others) -90;
					do move speed: vitesseMax heading: heading bounds:list_areas;
					//}
					//do goto target : direction speed : vitesseMax on:graph_path;
				}
				else {
					do goto target : direction speed : vitesseMax on:graph_path;
					if ( self . location = direction . location ) {
					do action: safe ;
					}
				}
			
		}
		action safe {
			create evacuees_safe {
				set self . color <- myself . color ;
				set self . taile <- myself . taile ;
				set self . location <- myself . location ;
				set self . duree <- myself . duree;
				set self . puissance <- myself . puissance; 
				set n_evacuees_safe <- n_evacuees_safe +1;
				set sum_puissance <- sum_puissance + self.puissance;
				set sum_duree_quitte <- sum_duree_quitte +self.duree;
			}
			do action: die ;
		}
		aspect base {
			draw shape : circle size : taile color : color ;
			//draw shape: circle color: rgb('red') size: range_voir*2+taile empty: true;
		}
	}
	species evacuees_mort skills : [ moving , situated ] control : fsm {
		float taile <- 10.0 ;
		rgb color <- rgb ( [ 0 , 0 , 0 ] ) ;
		aspect base {
			draw shape : circle size : taile color : color ;
		}
	}
	species evacuees_safe skills : [ moving , situated ] control : fsm {
		float taile ;
		rgb color ;
		int puissance;
		int duree ;
		aspect base {
			draw shape : circle size : taile color : color ;
		}
	}
	//feux
	species feux_potentiel skills : [ situated , visible ] control : fsm {
		rgb color <- rgb ( 'white' ) ;
		float taile <- float ( rnd ( feux_taile_max ) ) ;
		float rayon_effectuer <- feux_rayon_effectuer ;
		float vitesse_propagation <- feux_vitesse_propagation ;
		int vitesse_creer <- feux_vitesse_creer ;
		reflex burning {
				do action: burning ;
		}
		action burning {
			if flip (probabilite_burning ) {
			create feux {
				set self . color <- [ 255 , rnd ( 200 ) + 55 , 0 ] as rgb ;
				set self . taile <- myself . taile ;
				set self . location <- myself . location ;
				}
			do action: die ;
			}
		}
		aspect base {
			draw shape : circle size : taile color : color ;
		}
	}
	species feux skills : [ situated , visible ] control : fsm {
		rgb color <- rgb ( 'white' ) ;
		float taile <- float ( rnd ( feux_taile_max ) ) ;
		float rayon_effectuer <- feux_rayon_effectuer ;
		float vitesse_propagation <- feux_vitesse_propagation ;
		int vitesse_creer <- feux_vitesse_creer ;
		int duree <- 0 ;
		reflex enlargir {
			set duree <- duree + 1 ;
			if ( taile < 50.0 ) {
				set taile <- taile + ( 0.05 * duree ) ;
			}
			else {
				set taile <- taile - 10.0 ;
				if ( taile = 0 ) {
					do action: die ;
				}
			}
			if ( duree < 5 ) {
				create fumee number : vitesse_creer/2 {
					set self . color <- 'black' as rgb ;
					set self . taile <- myself . taile * 50 ;
					set self . location <- myself . location ;
				}
			}
		}
		reflex creer_feux {
			if ( duree < 3 ) {
				let agent_list <- ( self neighbours_at ( rayon_effectuer/20) of_species
				obtacles ) ;
				if (agent_list!=nil){
				ask agent_list {
					create feux_potentiel number : 1 {
						set self . color <- [ 255 , rnd ( 200 ) + 55 , 0 ] as rgb ;
						set self . taile <- 10.0 ;
						set self . location <- any_point_in ( one_of ( agent_list ) ) ;
						}
					}
				}
			}
		}
		reflex propager {
			let voisin <- ( self neighbours_at ( rayon_effectuer/20 ) of_species
			feux_potentiel ) ;
			let duree_propagation <-0;
			if (voisin !=nil){
				set duree_propagation <- duree_propagation +1;
				ask voisin {
					let distance <- myself distance_to self;
					if (myself.vitesse_propagation*duree_propagation >= distance){
						do action: burning ;
					}
				}
			}
		}
		reflex effectuer {
			let evacuees <- ( self neighbours_at ( rayon_effectuer ) of_species
			evacuees_urgent ) ;
			ask evacuees {
				do action: decrement_puissance ;
			}
		}
		aspect base {
			draw shape : circle size : taile color : color ;
		}
		aspect image {
			draw image : path_fire size : taile ;
		}
	}

	//fumme
	species fumee skills : [ moving , visible ] control : fsm {
		rgb color <- rgb ( 'black' ) ;
		float taile <- 10.0 ;
		float vitesse_deplacer <- vitesse_deplacer_max;
		int duree <- 0 ;
		reflex deplacer {
			do action: deplacer ;
			set duree <- duree + 1 ;
			if ( duree > 15 ) {
				do action: die ;
			}
		}
		action deplacer {
			do wander speed : vitesse_deplacer amplitude : ( 180 + rnd ( 90 ) )
			;
		}
		aspect base {
			draw shape : circle size : taile color : color ;
		}
		aspect image {
			draw image : path_smoke size : taile ;
		}
	}

	// sonneur	
	species sonneur_normal skills : [ situated , visible ] control : fsm {
		rgb color <- rgb ( 'green' ) ;
		float rayon_detection <- sonneur_rayon_detection;
		int duree <- sonneur_duree ;
		agent danger <- nil ;
		reflex normal when : ( danger = nil ) {
			let fumee_list <- ( ( self neighbours_at ( rayon_detection ) ) of_species
			fumee ) ;
			ask fumee_list {
				set myself . danger <- self ;
				}
			let feux_list <- ( ( self neighbours_at ( rayon_detection ) ) of_species
			feux ) ;
			ask feux_list {
				set myself . danger <- self ;
			}
			
		}
		reflex active when : ( ( danger != nil ) and ( sonneur_fois != 1 ) ) {
			set sonneur_fois <- 1 ;
			let sonneur_list <- list ( sonneur_normal ) ;
			set sonneur <- true ;
			ask sonneur_list {
				do action: active ;
			}
		}
		action active {
			create sonneur_active from : shape_file_sonneur number : 1 {
				set self . color <- 'red' as rgb ;
				set self . location <- myself . location ;
			}
			do action: die ;
		}
		aspect base {
			draw geometry : shape color : color ;
		}
	}
	species sonneur_active skills : [ situated , visible ] control : fsm {
		rgb color ;
		float rayon_detection ;
		int duree <- sonneur_duree ;
		reflex deactive {
			set duree <- duree - 1 ;
			if ( duree = 0 ) {
				do action: normal ;
			}
		}
		action normal {
			create sonneur_normal from : shape_file_sonneur number : 1 {
				set self . color <- 'white' as rgb ;
				set self . location <- myself . location ;
			}
			do action: die ;
		}
		aspect base {
			draw geometry : shape color : color ;
		}
	}
}
experiment Model9 type : gui {
/** Insert here the definition of the input and output of the model */
	parameter 'Nombre de evacuees' var : n_evacuees ;
	parameter 'Taile maximale' var : taile_max ; 
	parameter 'Puissance de evacuees' var : puissance_max ; 
	parameter 'Vitesse de evacuees' var : vitesse_normal ; 
	parameter 'Vitesse maximale de evacuees' var : vitesse_max ; 
	
	parameter 'Nombre de feux initial' var:n_feux;
	parameter 'Taile maximale de feux' var:feux_taile_max;
    parameter 'Rayon effectuer de feux' var:feux_rayon_effectuer;
	parameter 'Vitesse de propagation de feux' var:feux_vitesse_propagation;
	parameter 'Vitesse creer de feux' var:feux_vitesse_creer;
	
	parameter 'Vitesse de deplacement de fumme' var: vitesse_deplacer_max;
	
	parameter 'Rayon de detection de sonneur' var:sonneur_rayon_detection;
	parameter 'Duree de sonneur' var:sonneur_duree;
	
	parameter 'Sortie 1' var:sortie1;
	parameter 'Sortie 2' var:sortie2;
	
	output {
		inspect name: 'Agent' type : agent ;
		inspect name: 'Species' type : species ;
		display Incendie refresh_every : 1 {
			species obtacles aspect : base ;
			species evacuees_normal aspect : base ;
			species evacuees_urgent aspect : base ;
			species evacuees_mort aspect : base ;
			//species evacuees_safe aspect: base;
			//species path_emergent aspect:base;
			//species feux_potentiel aspect: base;
			species feux aspect : image ;
			//species fumee aspect : image ;
			species sonneur_normal aspect : base ;
			species sonneur_active aspect : base ;
		}
		monitor name: 'Nombre de evacuees quittes' value :n_evacuees_safe;
		monitor name: 'Nombre de evacuees morts' value :n_evacuees_mort;
		monitor name: 'Moyen de puissance' value :sum_puissance/n_evacuees_safe;
		monitor name: 'Moyen de temp quitte' value :sum_duree_quitte/n_evacuees_safe;
		display Evacuees { 
			chart td_diagram type : pie{
				data Safe value : n_evacuees_safe ;
				data Mort value : n_evacuees_mort;
				} 
			}
	}
}